// init.go
package main

import (
	"errors"
	"fmt"
	"image/jpeg"
	"image/png"
	"io/ioutil"
	"os"
	"runtime"
	"sync"

	"github.com/peterhellberg/tinypng"
	"github.com/widuu/goini"
)

var WaitGroup sync.WaitGroup
var apiKey string

func getSysPath() string {
	var path string
	if os.IsPathSeparator('\\') { //前边的判断是否是系统的分隔符
		path = "\\"
	} else {
		path = "/"
	}
	return path
}

func creatDir(path string) (string, string) {

	// 如果已经存在无视
	sPath := path + "源文件"
	zipPath := path + "压缩文件"
	os.Mkdir(sPath, os.ModePerm)
	os.Mkdir(zipPath, os.ModePerm)
	return sPath, zipPath
}

func fileExists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

func doTinypng(apiKey string, inputFilename string, outputFilename string) {
	res, err := tinypng.ShrinkFn(apiKey, inputFilename)
	if err != nil {
		fatalRed(res.Error+":", res.Message)
	}

	// Download the compressed PNG
	fmt.Println("下载", outputFilename)
	res.SaveAs(outputFilename)

	WaitGroup.Done()
}

func init() {
	conf := goini.SetConfig("conf.ini")
	apiKey = conf.GetValue("API", "apiKey")
	//fmt.Println("apiKey=", apiKey)

	if apiKey == "" {
		message := "请修改conf.ini中的apiKey的值."
		fmt.Println("Error:", errors.New(message))
		os.Exit(1)
	}
}

func main() {
	// 取到当前目录
	dir, _ := os.Getwd()
	//fmt.Println("当前目录：", dir)
	// 新建目录 源文件 压缩文件
	path := getSysPath()

	sPath, zipPath := creatDir(dir + path)

	dir_list, e := ioutil.ReadDir(sPath)
	if e != nil {
		fmt.Println("read dir error")
		return
	}
	for _, v := range dir_list {
		//fmt.Println(i, "=", v.Name())
		inputFilename := sPath + path + v.Name()
		outputFilename := zipPath + path + v.Name()
		if !fileExists(inputFilename) {
			//输入文件不存在
			fatalError("Input file does not exist.")
		}

		// Verify that the input file is a PNG or JPEG file
		//验证输入文件是PNG或JPEG文件
		if !validFileType(inputFilename) {
			fatalError(v.Name() + "不是一个图片文件")
			continue
		}

		//验证成功，开始压缩jpg or png 文件
		var err error
		apiKey, err = getAPIKeyFromEnv()
		check(err)
		WaitGroup.Add(1)

		fmt.Println("压缩:", v.Name())
		go doTinypng(apiKey, inputFilename, outputFilename)
	}

	WaitGroup.Wait()

	fmt.Println("图片压缩完成！")
}

func getAPIKeyFromEnv() (string, error) {

	//apiKey = "ziCMCUXGDHy1TJQmGCKWHx577oe4YmXs"

	return apiKey, nil
}

func validFileType(fn string) bool {
	return validPNGFile(fn) || validJPEGFile(fn)
}

// PNG

func validPNGFile(fn string) bool {
	pngImage, err := os.Open(fn)

	check(err)

	defer pngImage.Close()

	_, err = png.DecodeConfig(pngImage)

	if err != nil {
		return false
	}

	return true
}

// JPEG

func validJPEGFile(fn string) bool {
	jpegImage, err := os.Open(fn)

	check(err)

	defer jpegImage.Close()

	_, err = jpeg.DecodeConfig(jpegImage)

	if err != nil {
		return false
	}

	return true
}

// Fatal

func check(err error) {
	if err != nil {
		fatal(red("Error:"), err)
	}
}

func fatal(v ...interface{}) {
	fmt.Println(v...)

	//os.Exit(1)
}

func fatalError(message string) {
	fatalRed("Error:", message)
}

func fatalRed(title, message string) {
	fatal(red(title), message)
}

func fatalGreen(title, message string) {
	fatal(green(title), message)
}

// Color

func color(c, s string) string {
	// No ANSI escape sequences for Windows
	if runtime.GOOS == "windows" {
		return s
	}

	return "\033[" + c + "m" + s + "\033[0m"
}

func red(s string) string {
	return color("0;31", s)
}

func green(s string) string {
	return color("0;32", s)
}
